//
//  YJHomeViewController.swift
//  YJWeiBo
//
//  Created by Jim1024 on 2017/1/10.
//  Copyright © 2017年 Jim1024. All rights reserved.
//

import UIKit

class YJHomeViewController: YJBaseTableViewController {
    
    fileprivate let kReuseIdentifier = "ReuseIdentifier"
    
    /// 微博数据
    var statuses: [YJStatus]? {
        didSet {
            self.tableView.reloadData()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // 登陆以后才做后面的操作
        if !YJUserAccountViewModel.sharedInstance.userLogin {
            return
        }
        
        // 设置导航栏
        setupNavigationBar()
        setupTitleButton()
        prepareTableView()
        
        // 显示FPS
        UIApplication.shared.keyWindow?.showFPSInCenter()
    }
    
    fileprivate func prepareTableView() {
        tableView.register(YJStatusCell.self, forCellReuseIdentifier: kReuseIdentifier)
        
//        tableView.estimatedRowHeight = 200
//        tableView.rowHeight = UITableViewAutomaticDimension
        
        tableView.backgroundColor = UIColor(white: 237 / 255.0, alpha: 1)
        // MARK: - test...
        tableView.backgroundColor = UIColor.green
        // 取消cell之间的分割线
        tableView.separatorStyle = UITableViewCellSeparatorStyle.none
        
        // 自定义的下拉刷新控件
        tableView.addPullDownRefreshHandler { [weak self] in
            self?.loadNewStatus()
        }
        tableView.startRefreshing()
    }
    
    fileprivate func setupNavigationBar() {
        navigationItem.leftBarButtonItem = UIBarButtonItem(imageName: "navigationbar_friendsearch", target: self, action: #selector(didClickLeftItem))
        navigationItem.rightBarButtonItem = UIBarButtonItem(imageName: "navigationbar_pop", target: self, action: #selector(didClickRightItem))
    }
    
    fileprivate func setupTitleButton() {
        let name = YJUserAccountViewModel.sharedInstance.userAccount?.screen_name
        let titleButton = YJHomeTitleButton(title: name, imageName: "navigationbar_arrow_down")
        titleButton.addTarget(self, action: #selector(didClickTitleButton(_:)), for: .touchUpInside)
        
        navigationItem.titleView = titleButton
    }
    
    /**
     显示下拉刷新的条数
     
     - parameter count: 下拉刷新的条数
     */
    fileprivate func showTipLabel(_ count: Int) {
        tipLabel.text = count == 0 ? "没有新的微博数据" : "更新了\(count)条微博数据"
        
        // 动画叠加导致label还会往下走,UIView动画的底层也是核心动画
        let animationKeys = tipLabel.layer.animationKeys()
        if animationKeys != nil {
            JPrint("有动画在运行,移除: \(animationKeys)")
            // 移除之前的动画
            tipLabel.layer.removeAllAnimations()
        }
        
        // 动画
        UIView.animate(withDuration: YJDefaultDuration * 2, animations: {
            self.tipLabel.frame.origin.y = 44
        }) { (_) in
            UIView.animate(withDuration: YJDefaultDuration * 2, delay: YJDefaultDuration * 3, options: UIViewAnimationOptions(rawValue: 0), animations: { 
                self.tipLabel.frame.origin.y = -64
            }, completion: nil)
        }
    }
    
    // MARK: - 加载数据
    fileprivate func loadNewStatus() {
        // 获取id最大的微博, 当没有微博数据,传入0加载最新20条微博数据
        let since_id = self.statuses?.first?.id ?? 0
        
        // 使用VM加载数据
        YJStatusViewModel.share.loadStatus(since_id, max_id: 0) { (statuses, error) in
            self.tableView.endRefreshing()
            if error != nil {
                JPrint("加载微博数据出错了: \(error)")
                return
            }
            
            let count = statuses?.count ?? 0
            
            if since_id > 0 {
                self.showTipLabel(count)
            }
            
            if count == 0 {
                JPrint("没有加载到微博")
                return
            }
            
            // 下拉刷新
            if since_id > 0 {
                JPrint("下拉刷新count: \(count)")
                // 下拉刷新,需要将新获取到的数据添加到现有数据的前面,并且重新赋值
                self.statuses = statuses! + self.statuses!
            } else {
                JPrint("第一次加载最新微博count: \(count)")
                // 加载最新20条数据
                self.statuses = statuses
                
                // 当第一次获取最新数据完成后再添加上拉加载更多功能
                self.tableView.addInfiniteScrolling { [weak self] in
                    self?.loadMoreStatus()
                }
            }
        }
    }
    
    /// 加载更多微博数据,上拉加载数据
    fileprivate func loadMoreStatus() {
        let max_id = self.statuses?.last?.id ?? 0
        
        YJStatusViewModel.share.loadStatus(0, max_id: max_id) { (statuses, error) in
            // 结束上拉加载更多数据
            self.tableView.infiniteScrollingView.stopAnimating()
            
            if error != nil {
                JPrint("上拉加载微博数据出错了: \(error)")
                return
            }
            
            let count = statuses?.count ?? 0
            if count == 0 {
                JPrint("没有加载到微博")
                return
            }
            
            // 上拉加载更多数据,将新的数据拼接到现有数据的后面
            self.statuses = self.statuses! + statuses!
            JPrint("上拉加载更多数据: \(statuses?.count)")
            JPrint("最终微博数据条数: \(self.statuses?.count)")
        }
    }
    
    // MARK: - UIAction
    
    @objc fileprivate func didClickTitleButton(_ button: YJHomeTitleButton) {
        button.isSelected = !button.isSelected
        
        UIView.animate(withDuration: YJDefaultDuration) {
            button.imageView?.transform = button.isSelected ? CGAffineTransform(rotationAngle: CGFloat.pi - 0.01) : CGAffineTransform.identity
        }
        
        if button.isSelected {
            // iOS8 以后 popoverPresentationController
            let popoverVC = YJPopoverViewController()
            popoverVC.dismissHandle = {
                self.didClickTitleButton(button)
            }
            
            popoverVC.modalPresentationStyle = .popover
            // 设置popoverPresentationController的代理,
            popoverVC.popoverPresentationController?.delegate = self
            popoverVC.popoverPresentationController?.backgroundColor = UIColor(white: 0, alpha: 0.5)
            // popover的箭头指向titeView,默认指向左上角
            popoverVC.popoverPresentationController?.sourceView = navigationItem.titleView
            // 设置sourceView.bounds给sourceRect
            var rect = navigationItem.titleView!.bounds
            rect.origin.y += 5
            popoverVC.popoverPresentationController?.sourceRect = rect
            
            // 设置popover显示的大小
            popoverVC.preferredContentSize = CGSize(width: view.frame.width * 0.5, height: CGFloat(44 * popoverVC.titles.count))
            
            present(popoverVC, animated: true, completion: nil)
        }
    }
    
    @objc fileprivate func didClickLeftItem() {
        JPrint(#function)
    }
    
    @objc fileprivate func didClickRightItem() {
        JPrint(#function)
    }
    
    // MARK: - 懒加载
    
    fileprivate lazy var tipLabel: UILabel = {
        let label = UILabel()
        
        label.backgroundColor = UIColor.orange
        label.textColor = UIColor.white
        label.font = UIFont.systemFont(ofSize: 16)
        label.textAlignment = .center
        label.alpha = 0.9
        label.frame = CGRect(x: 0, y: -64, width: UIScreen.width, height: 44)
        
        // 往导航栏上面添加
        self.navigationController?.navigationBar.insertSubview(label, at: 0)
        
        return label
    }()
}

// MARK: - table view data source & delegate
extension YJHomeViewController {
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return statuses?.count ?? 0
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: kReuseIdentifier, for: indexPath) as! YJStatusCell
        
        cell.status = statuses?[indexPath.row]
        return cell
    }
    
    // 取消cell的选中
    override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
        return false
    }
    
    /*
     tableView的优化:
     1.cell复用
     2.图片加载(耗时操作)使用子线程(SDWebImage)
     3.IO操作(耗时操作),读取文件和写入文件,最好是在cell显示之前将文件的内容读取出来,保存在内存中
     4.缓存tableViewCell的行高,如果根据cell的约束确定行高,每当显示之前都需要计算
     5.不要使用预估行高,预估行高会使tableView的cell在显示之前才去计算
     6.dequeueReusableCellWithIdentifier:forIndexPath: 会再次调用 tableView:heightForRowAtIndexPath,所以尽量少用
     7.cell里面的控件使用懒加载.用不到的隐藏掉,不要在cellForRowAtIndexPath里面创建和删除子控件
     8.在tableView:cellForRowAtIndexPath:里面尽量少的计算
     9.使用图层圆角,阴影,会影响性能
     10.view或图层尽量使用不透明的
     11.图片的拉伸和压缩等都会影响性能
     12.cell在滚动的时候不要去做动画
     13.cell里面的view的层次不要太多
     */
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        // 将行高缓存到模型中,cell的内容是根据模型来的
        // 1.去模型中看看有没有缓存的行高
        let status = self.statuses![indexPath.row]
        if status.rowHeight != nil {
            // 模型中保存了行高
//            JPrint("模型中保存的行高: \(indexPath), \(status.rowHeight!)")
            return status.rowHeight!
        }
        
        /********** 使用此方法会产生递归调用!! ************/
        //        let cell = tableView.dequeueReusableCellWithIdentifier(ReuseIdentifier, forIndexPath: indexPath)
        let cell = tableView.dequeueReusableCell(withIdentifier: kReuseIdentifier) as! YJStatusCell
        
        // 将status赋值给cell,cell会根据status里面的内容和autoLayout,会重新计算布局,cell没有拿去显示,只是用来填充内容计算行高
        cell.status = status
        
        // 根据autolayout和cell控件的内容.获取cell的高度
        let rowHeight = cell.systemLayoutSizeFitting(UILayoutFittingExpandedSize).height
        
        // 将计算好的行高保存到模型里面
        status.rowHeight = rowHeight
        
//        JPrint("计算出来的行高: \(indexPath), \(rowHeight)")
        
        return rowHeight
    }
}

// MARK: - 实现 UIPopoverPresentationControllerDelegate协议
extension YJHomeViewController: UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return .none
    }
    
    func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {
        // 让箭头转下来
        let titleButton = navigationItem.titleView as! YJHomeTitleButton
        didClickTitleButton(titleButton)
        
        return true
    }
}
